#ifndef ___EVENTPP_TCP_CONNECTION_H_
#define ___EVENTPP_TCP_CONNECTION_H_

struct evbuffer;

namespace eventpp
{
  class net_base;
  class tcp_handler;

	class tcp_connection {
		enum status {
			socked_closed,
			socket_connecting,
			socket_connected,
		};

	public:
		tcp_connection(net_base &	base, tcp_handler * handler);
		~tcp_connection();

		int connect( sockaddr *sa, int sa_len );
		bool connected() const { return status_ == socket_connected; }

        size_t read(void * data, size_t len);
		bool write( const void * data, size_t len );
		//void write( evbuffer * out ) {
		//	if ( ! connected() ) return ;			
		//	bufferevent_write_buffer( bev_, out );
		//}
		void close();

        evbuffer * get_input() {
            return bufferevent_get_input( bev_ );
        }
        evbuffer * get_output() {
            return bufferevent_get_output( bev_ );
        }

        void set_output_buffer_limit(size_t limit) {
            max_output_ = limit;
        }

        size_t output_buffer_limit() const {
            return max_output_;
        }

		int on_accepted(evutil_socket_t sock, sockaddr *sa, int sa_len);

	private:
		void on_connected();
		static void be_read_cb(struct bufferevent *bev, void *ctx);
		static void be_write_cb(struct bufferevent *bev, void *ctx);
		static void be_event_cb(struct bufferevent *bev, short what, void *ctx);

	private:
		evutil_socket_t	sock_;
		sockaddr_in sa_;
		net_base &	base_;
		tcp_handler *	handler_;
		bufferevent *	bev_;
        size_t          max_output_;

		status			status_;
	};
}
#endif
